package com.examplemartin.jpademo.service.sell;

import com.examplemartin.jpademo.bean.AjaxResult;
import com.examplemartin.jpademo.dao.SellDao;
import com.examplemartin.jpademo.pojo.po.UserPO;
import com.examplemartin.jpademo.pojo.po.good.GoodPO;
import com.examplemartin.jpademo.pojo.po.repository.sell.SellOutDetailPO;
import com.examplemartin.jpademo.pojo.po.repository.sell.SellOutPO;
import com.examplemartin.jpademo.pojo.po.sell.SellDetailPO;
import com.examplemartin.jpademo.pojo.po.sell.SellPO;
import com.examplemartin.jpademo.pojo.po.stock.SummGoodPO;
import com.examplemartin.jpademo.pojo.vo.purchase.RepoinfoVO;
import com.examplemartin.jpademo.service.GoodService;
import com.examplemartin.jpademo.service.RepoInfoService;
import com.examplemartin.jpademo.service.StockService;
import com.examplemartin.jpademo.service.sellout.SellOutService;
import com.examplemartin.jpademo.service.stock.SummGoodService;
import com.examplemartin.jpademo.util.SessionUtil;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.util.*;

@Service("sellService")
@Component
public class SellService {

    public static Integer SELL_STATUS_SPARE = 0;
    public static Integer SELL_STATUS_RUNNING = 1;
    public static Integer SELL_STATUS_LESSGOOG = 2;
    public static Integer SELL_STATUS_FINISH = 3;
    public static Integer SELL_STATUS_LOCK = 4;

    public static String SELL_STATUS_SPARE_NAME = "编制...";
    public static String SELL_STATUS_RUNING_NAME = "执行...";
    public static String SELL_STATUS_LESSGOOG_NAME = "缺货...";
    public static String SELL_STATUS_FINISH_NAME = "结束...";
    public static String SELL_STATUS_LOCK_NAME = "废弃...";

    public static HashMap<Integer, String> SELL_STATUS_MAP = new HashMap<>();

    static {
        SELL_STATUS_MAP.put(SELL_STATUS_SPARE, SELL_STATUS_SPARE_NAME);
        SELL_STATUS_MAP.put(SELL_STATUS_RUNNING, SELL_STATUS_RUNING_NAME);
        SELL_STATUS_MAP.put(SELL_STATUS_LESSGOOG, SELL_STATUS_LESSGOOG_NAME);
        SELL_STATUS_MAP.put(SELL_STATUS_FINISH, SELL_STATUS_FINISH_NAME);
        SELL_STATUS_MAP.put(SELL_STATUS_LOCK, SELL_STATUS_LOCK_NAME);
    }

    @Resource
    private SellDao sellDao;
    @Resource
    private GoodService goodService;
    @Resource
    private RepoInfoService repoInfoService;
    @Resource
    private SellDetailService sellDetailService;
    @Resource
    private StockService stockService;

    /***
     * 按id查找 订单
     */
    public SellPO findById(Long id) {
        return sellDao.findById(id).get();
    }

    /**
     * 销售订单列表 页面
     */
    public List<SellPO> findAll() {
        List<SellPO> all = sellDao.findAll();
        return all;
    }

    public SellPO save(SellPO sellPO) {
        SellPO save = sellDao.save(sellPO);
        return save;
    }

    /**
     * 生成新建  销售订单
     *
     * @param sellPO
     *
     * @return
     */
    public AjaxResult savesellPOAjax(SellPO sellPO, UserPO userPO) {

        // 库存信息
        List<RepoinfoVO> allGroupByGoodId = repoInfoService.findAllGroupByGoodId();
        //责任人
        UserPO loninUser = SessionUtil.getLoninUser();

//        检查是否缺货
        Boolean LESSGOOD = false;
        List<SellDetailPO> sellDetailPOList = sellPO.getSellDetailPOList();
        // 循环判断是否出现缺货 -- 编制阶段 不判断, 审核提交时判断生成缺货单
 /*       for (SellDetailPO sellDetailPO : sellDetailPOList) {
            GoodPO goodPO = sellDetailPO.getGoodPO();
            Integer goodcount = sellDetailPO.getGoodcount();
            for (RepoinfoVO repoinfoVO : allGroupByGoodId) {
                GoodPO goodPO1 = repoinfoVO.getGoodPO();
                Integer goodcount1 = repoinfoVO.getGoodcount();
                if (goodPO1.getId().longValue() == goodPO.getId().longValue()) {
                    if (goodcount1 < goodcount) {
                        LESSGOOD = true;
                    }
                    break;
                }

            }
            if (LESSGOOD == true) {
                break;
            }

        }*/


        SellPO newSellPO = new SellPO();
        // 销售订单号
        newSellPO.setName(sellPO.getName());
        // 销售订单日期
        newSellPO.setCreateTime(new Date());
        // 销售订单顾客
        newSellPO.setCustPO(sellPO.getCustPO());
        // 销售订单注释
        newSellPO.setComment(sellPO.getComment());
        // 销售订单责任人
        newSellPO.setUserPO(loninUser);
        // 销售订单need日期
        newSellPO.setNeed(sellPO.getNeed());
        // 订单状态 -- 缺货 , 待审 -- 编制阶段 不判断, 审核提交时判断生成缺货单
        /*if (LESSGOOD) {
            newSellPO.setStatus(SellService.SELL_STATUS_LESSGOOG);
        } else {
            newSellPO.setStatus(SellService.SELL_STATUS_SPARE);
        }*/
        newSellPO.setStatus(SellService.SELL_STATUS_SPARE);
        // 生成订单
        newSellPO = sellDao.save(newSellPO);
        // 保存订单

        // 生成明细
        newSellPO.setSellDetailPOList(new ArrayList<SellDetailPO>());
        for (SellDetailPO sellDetailPO : sellPO.getSellDetailPOList()) {
            SellDetailPO newDetail = new SellDetailPO();
            newDetail.setSellPO(newSellPO);

            GoodPO byIdgood = goodService.findById(sellDetailPO.getGoodPO().getId());
            newDetail.setGoodPO(byIdgood);


            newDetail.setPrice(sellDetailPO.getPrice());
            newDetail.setGoodcount(sellDetailPO.getGoodcount());
            // 保存明细
            SellDetailPO save = sellDetailService.save(newDetail);
            newSellPO.getSellDetailPOList().add(save);

        }
        // 再次保存订单
        SellPO save = sellDao.save(newSellPO);
        if (save != null) {
            return AjaxResult.success(200, "新建销售订单", null);
        } else {
            return AjaxResult.fail(500, "订单建立失败");
        }


    }

    /**
     * 保存修改的销售订单
     *
     * @param sellPO
     *
     * @return
     */
    public AjaxResult savemodifysellPOAjax(@RequestBody SellPO sellPO) {

        SellPO oldsell = sellDao.findById(sellPO.getId()).get();
        oldsell.setNeed(sellPO.getNeed());
        oldsell.setCustPO(sellPO.getCustPO());
        oldsell.setName(sellPO.getName());
        oldsell.setComment(sellPO.getComment());

        // 删除订单
        for (SellDetailPO sellDetailPO : oldsell.getSellDetailPOList()) {
            sellDetailService.deleteById(sellDetailPO.getId());
        }

//        sellDao.delete(oldsell);
//        oldsell.setId(null);
        oldsell.setUpdateTime(new Date());
        oldsell.setSellDetailPOList(new ArrayList<SellDetailPO>());
        SellPO save = sellDao.save(oldsell);

        // 添加明细
        List<SellDetailPO> sellDetailPOList1 = sellPO.getSellDetailPOList();
        for (SellDetailPO sellDetailPO : sellDetailPOList1) {
            sellDetailPO.setId(null);
            sellDetailPO.setSellPO(save);
            oldsell.getSellDetailPOList().add(sellDetailPO);
            sellDetailService.save(sellDetailPO);
        }
        oldsell.setStatus(0);
        save = sellDao.save(oldsell);


//        // 删除明细
//        List<SellDetailPO> sellDetailPOList = oldsell.getSellDetailPOList();
//        for (SellDetailPO sellDetailPO : sellDetailPOList) {
//            oldsell.getSellDetailPOList().remove(sellDetailPO);
////            sellDetailService.deleteById(sellDetailPO.getId());
//        }
//        sellDao.save(oldsell);
        return AjaxResult.success(200, "订单修改完毕", null);
    }

    @Resource
    private SellOutService sellOutService;

    /**
     * 销售订单列表 审核页面使用
     * 按状态生成 日期排序
     */
    public List<SellPO> findAllByStatusOOrderByNeed(Integer status) {
        List<SellPO> all = sellDao.findAllByStatusOrderByNeedDesc(status);
        return all;
    }

    public Map<String, Object> getSellOutList(Long sellid) {
        HashMap<String, Object> ret = new HashMap<>();

        SellPO sellPO = sellDao.findById(sellid).get();
        List<SellOutPO> sellOutList = sellOutService.findAllBySellPO(sellPO);

        // 已入库 入库单数
        ret.put("selloutSum", sellOutList.size());

        // 入库明细合计
        HashMap<Long, Integer> goodmap = new HashMap<>();
        // 初始化
        List<SellDetailPO> sellDetailPOList = sellPO.getSellDetailPOList();
        for (SellDetailPO sellDetailPO : sellDetailPOList) {
            goodmap.put(sellDetailPO.getGoodPO().getId(),0);
        }

        for (SellOutPO sellOutPO : sellOutList) {
            List<SellOutDetailPO> detail = sellOutPO.getSellOutDetailPOList();

            for (SellOutDetailPO gooddetail : detail) {
                Long goodid = gooddetail.getGoodPO().getId();
                Integer goodcount = goodmap.get(goodid);
                goodmap.put(goodid,goodcount+ gooddetail.getGoodcount());
            }
        }
        ret.put("goodmap", goodmap);

        return ret;
    }

    /**
     * 把订单 转换为 .... 状态
     * /purchase/auditPurPO.ajax
     *
     * @param newSell
     *
     * @return
     */
    public AjaxResult auditSellPOAjax(SellPO newSell) {


        SellPO oldSell = sellDao.findAllById(newSell.getId());

        if (newSell.getStatus() == oldSell.getStatus()) {
            return AjaxResult.fail(500, "请选择状态");
        }

        /*
    public static String SELL_STATUS_SPARE_NAME = "编制...";
    public static String SELL_STATUS_RUNING_NAME = "执行...";
    public static String SELL_STATUS_LESSGOOG_NAME = "缺货...";
    public static String SELL_STATUS_FINISH_NAME = "结束...";
    public static String SELL_STATUS_LOCK_NAME = "废弃...";
        * */

        // 0 编制中
        // 1 运行中
        // 2 缺货 -- 缺货提交后 , 销售员能看见, 可以再次编译提交到编制状态 , 所以在审核中看不到取货状态
        // 3 结束
        //4 lock
        // 不允许在下拉列表中出现 缺货选择
        SellPO save = null;

        //0 -> x 可以 1 3 4
        // 0-1 判断是否缺货, 取货设为缺货状态
        if (oldSell.getStatus() == 0) {
            if (newSell.getStatus() == 2) {
                return AjaxResult.fail(500, "不能直接转缺货");
            } else {
                oldSell.setStatus(newSell.getStatus());
                if (newSell.getStatus() == 1) {
                    if (isLess(oldSell)) {
                        oldSell.setUpdateTime(new Date());
                        oldSell.setStatus(SELL_STATUS_LESSGOOG);
                        sellDao.save(oldSell);
                        return AjaxResult.success(200, "生成 销售 缺货单", null);

                    } else {
                        oldSell.setUpdateTime(new Date());
                        oldSell.setStatus(SELL_STATUS_RUNNING);
                        // 备货操作
                        spareGood(newSell);
                        sellDao.save(oldSell);
                        return AjaxResult.success(200, "订单进入:" + SELL_STATUS_MAP.get(newSell.getStatus()) + " 状态", null);

                    }
                } else {
                    oldSell.setUpdateTime(new Date());
                    oldSell.setStatus(newSell.getStatus());
                    sellDao.save(oldSell);
                    return AjaxResult.success(200, "订单进入:" + SELL_STATUS_MAP.get(newSell.getStatus()) + " 状态", null);
                }
            }


        }


        // 1 -> 0 -- 查有误出库
        // 1--3 直接切换
        // 1--4  -- 查有误出库
        if (oldSell.getStatus() == 1) {
            if (newSell.getStatus() == 3) {
                oldSell.setStatus(newSell.getStatus());
                oldSell.setUpdateTime(new Date());
                sellDao.save(oldSell);
                return AjaxResult.success(200, "订单进入:" + SELL_STATUS_MAP.get(newSell.getStatus()) + " 状态", null);
            } else {
                /**
                 * 这样要补充 判断是否有出库单
                 */
                return AjaxResult.fail(500, "不能有出库");
            }
        }


        //这里简化 2 缺货
        // 2 -x 不允许 -- 审核中不能看到2 状态
        // 2 ->0,1 重新判断 是否缺货
        // 2-> x 缺货已提交  不能撤回
/*        if(oldSell.getStatus() == 2){
            if(newSell.getStatus() == 1){
                // 重新提交,判断是否有缺货
                if(isLess(oldSell)){
                    oldSell.setStatus();
                }

            }else{
                return AjaxResult.fail(500,"缺货已提交 不能撤回");
            }
        }*/


        // 3-x  不允许3 结束
        if (oldSell.getStatus() == 3) {
            return AjaxResult.fail(500, "已入库,不能转换");
        }

        // 4-0 允许
        // 4-x 不允许 必须先到编制状态
        if (oldSell.getStatus() == 4) {
            if (newSell.getStatus() == 0) {
                oldSell.setStatus(0);
                oldSell.setUpdateTime(new Date());
                sellDao.save(oldSell);
                return AjaxResult.success(200, "订单进入:" + SELL_STATUS_MAP.get(newSell.getStatus()) + " 状态", null);

            } else {
                return AjaxResult.fail(500, "请先转到编制状态");
            }
        }

        return AjaxResult.fail(500, "状态转换出错");
    }

    // 缺货 状态判断
    private Boolean isLess(SellPO sellPO) {
        // 标志
        Boolean LESSGOOD = false;

        List<SellDetailPO> sellDetailPOList = sellPO.getSellDetailPOList();
        // 循环判断是否出现缺货 -- 编制阶段 不判断, 审核提交时判断生成缺货单
        for (SellDetailPO sellDetailPO : sellDetailPOList) {
            GoodPO goodPO = sellDetailPO.getGoodPO();
            Integer goodcount = sellDetailPO.getGoodcount();
            SummGoodPO summforGoodPO = summGoodService.findByGoodPO(goodPO);
            if (summforGoodPO.getGoodcount() < goodcount) {
                LESSGOOD = true;
                break;
            }
        }
        return LESSGOOD;
    }

    public List<SellPO> findByStatus(Integer sellStatusRunning) {
        List<SellPO> byStatus = sellDao.findByStatus(sellStatusRunning);
        return byStatus;
    }

    @Resource
    private SummGoodService summGoodService;
    // 仓储备货处理 -- 这里假设 不同仓库的库存商品 不会产生 冲突
    private Boolean spareGood(SellPO sellPO) {
        Boolean ret = true;

        sellPO = sellDao.findById(sellPO.getId()).get();

        // 销售单明细条目
        List<SellDetailPO> repodetaillist = sellPO.getSellDetailPOList();

        // 老库存 用于回滚
        ArrayList<SummGoodPO> summGoodlist = new ArrayList<>();

        // 所有库存信息
        List<SummGoodPO> all = summGoodService.findAll();

        // 修改库存
        for (SellDetailPO detailPO : repodetaillist) {
            GoodPO goodPO = detailPO.getGoodPO();
            Integer goodcount = detailPO.getGoodcount();
            SummGoodPO oldsumm = summGoodService.findByGoodPO(goodPO);
            summGoodlist.add(oldsumm);
            oldsumm.setGoodspare(goodcount);
            oldsumm.setGoodcount(oldsumm.getGoodcount()-goodcount);
            summGoodService.save(oldsumm);

        }



        return ret;
    }


    // 查找补货单
    public List<SellPO> findOutSupply(){
        return sellDao.findByStatus(SellService.SELL_STATUS_LESSGOOG);
    }
}